import Fluent
import FluentSQL
import MySQLNIO
import Redis
import Vapor

struct AlbumController: RouteCollection, Logging {
  
  func boot(routes: any RoutesBuilder) throws {
    let albums = routes.grouped("\(RouteEnum.albums.rawValue)")
    albums.post("\(RouteEnum.create.rawValue)", use: create)
    let protected = albums.grouped(AuthMiddleware())
    protected.get("\(RouteEnum.fetch.rawValue)", use: fetch)
    protected.get("\(RouteEnum.search.rawValue)", use: search)
    protected.get("\(RouteEnum.category.rawValue)", ":category", use: fetchByCategory)
    protected.get("\(RouteEnum.tag.rawValue)", ":tagID", use: getByTag)
    protected.patch("\(RouteEnum.increasePlayCount.rawValue)", ":albumID", use: increasePlayCount)
    protected.get(":albumID", use: fetchAlbumByID)
    
    // 添加公共端点，用于分享功能
    albums.get("public", ":albumID", use: fetchAlbumPublic)
    
    // 添加生成分享链接端点
    protected.get("\(RouteEnum.share.rawValue)", ":albumID", use: getShareLink)
  }
  
  // 生成分享链接的方法
  @Sendable
  func getShareLink(req: Request) async throws -> ShareLinkResponse {
    // 获取用户认证信息
    let userID = try req.authenticatedUserID
    
    // 获取专辑ID
    guard let albumID = req.parameters.get("albumID", as: UUID.self) else {
      throw Abort(.badRequest, reason: "无效的专辑 ID")
    }
    
    // 检查是否是系统专辑ID
    let systemAlbumID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    if albumID == systemAlbumID {
      throw Abort(.notFound, reason: "专辑不存在")
    }
    
    // 检查专辑是否存在
    guard let album = try await Album.query(on: req.db)
      .filter(\.$id == albumID)
      .filter(\.$isDeleted == false)
      .first() else {
      throw Abort(.notFound, reason: "专辑不存在")
    }
    
    // 生成分享链接
    let baseURL = "https://www.bayanarabic.cn/audio"
    let shareURL = "\(baseURL)/\(albumID)"
    
    return ShareLinkResponse(
      id: try album.requireID(),
      title: album.title,
      shareURL: shareURL
    )
  }
  
  // 新增的公开接口，用于分享功能，无需认证
  @Sendable
  func fetchAlbumPublic(req: Request) async throws -> PublicAlbumResponse {
    LogManager.shared.info("开始处理公共专辑请求", context: "albumID: \(req.parameters.get("albumID", as: String.self) ?? "未知")")
    
    guard let albumID: UUID = req.parameters.get("albumID", as: UUID.self) else {
      LogManager.shared.error("无效的专辑ID格式", context: "参数值: \(req.parameters.get("albumID") ?? "空")")
      throw Abort(.badRequest, reason: "无效的专辑 ID")
    }
    
    // 检查是否是系统专辑ID
    let systemAlbumID: UUID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    if albumID == systemAlbumID {
      LogManager.shared.warning("尝试访问系统专辑", context: "albumID: \(albumID)")
      throw Abort(.notFound, reason: "专辑不存在")
    }
    
    // 构建缓存键
    let cacheKey: RedisKey = CacheConfig.KeyBuilder.albumPublic(albumID: albumID)
    LogManager.shared.debug("尝试从缓存获取专辑", context: "cacheKey: \(cacheKey)")
    
    // 尝试从缓存获取
    if let cachedResponse = try? await req.cache.get(
      forKey: cacheKey,
      as: PublicAlbumResponse.self,
      from: req.redis
    ) {
      LogManager.shared.debug("命中缓存", context: "albumID: \(albumID)")
      return cachedResponse
    }
    
    // 从数据库获取专辑信息
    guard let album: Album = try await Album.query(on: req.db)
      .filter(\.$id == albumID)
      .filter(\.$isDeleted == false)
      .with(\.$tags)
      .first() else {
      LogManager.shared.warning("专辑不存在或已删除", context: "albumID: \(albumID)")
      throw Abort(.notFound, reason: "专辑不存在")
    }
    
    LogManager.shared.info("成功获取专辑数据", context: """
      albumID: \(albumID)
      title: \(album.title)
      category: \(album.category.rawValue)
      audioCount: \(album.audioCount)
    """)
    
    // 获取专辑下的音频列表（所有音频）
    let audioList = try await Audio.query(on: req.db)
      .filter(\.$album.$id == albumID)
      .filter(\.$isDeleted == false)
      .sort(\.$createdAt, .ascending)
      .all()
      .map { audio in
        PublicAudioItem(
          id: try! audio.requireID(),
          title: audio.title,
          author: audio.author ?? "",
          duration: audio.duration,
          cover: audio.cover
        )
      }
    
    LogManager.shared.debug("获取到音频列表", context: "数量: \(audioList.count)")
    
    // 构建响应
    let response = PublicAlbumResponse(
      id: try album.requireID(),
      title: album.title,
      description: album.description,
      cover: album.cover,
      audioCount: album.audioCount,
      playCount: album.playCount,
      category: album.category,
      tags: album.tags.map { TagResponse(id: try! $0.requireID(), name: $0.name) },
      audios: audioList,
      shareUrl: "https://www.bayanarabic.cn/audio/\(albumID)"
    )
    
    // 缓存响应
    do {
      try await req.cache.set(
        response,
        forKey: cacheKey,
        duration: CacheConfig.Duration.long,
        type: .album,
        on: req.redis
      )
      LogManager.shared.info("成功缓存专辑公共数据", context: "albumID: \(albumID)")
    } catch {
      LogManager.shared.error("缓存公共专辑信息失败", context: "\(error)")
    }
    
    return response
  }
  
  @Sendable
  func create(req: Request) async throws -> BasicResponse {
    
    let input = try req.content.decode(Album.Create.self)
    let album = Album(
      title: input.title,
      description: input.description,
      cover: input.cover,
      audioCount: 0,
      playCount: 0,
      favoriteCount: 0,
      isDeleted: false,
      createdAt: Date(),
      updatedAt: Date(),
      category: input.category
    )
    try await album.save(on: req.db)
    
    if let tagNames = input.tagNames {
      for tagName in tagNames {
        let tag =
        try await Tag.query(on: req.db)
          .filter(\.$name == tagName)
          .first()
        ?? Tag(
          name: tagName,
          isDeleted: false,
          createdAt: Date(),
          updatedAt: Date()
        )
        if tag.id == nil {
          try await tag.save(on: req.db)
        }
        let albumTag = AlbumTag(
          albumID: try album.requireID(),
          tagID: try tag.requireID(),
          isDeleted: false,
          createdAt: Date(),
          updatedAt: Date()
        )
        try await albumTag.save(on: req.db)
      }
    }
    return BasicResponse(
      success: true,
      message: "专辑创建成功",
      id: album.id
    )
  }
  @Sendable
  func increasePlayCount(req: Request) async throws -> Response {
    let albumID = req.parameters.get("albumID", as: UUID.self)
    let album = try await Album.find(albumID, on: req.db)
    guard let targetAlbum = album else {
      throw Abort(.notFound, reason: "专辑不存在")
    }
    targetAlbum.playCount += 1
    try await targetAlbum.save(on: req.db)
    return Response(
      status: .ok,
      headers: ["Content-Type": "application/json"],
      body: .init(string: "{}")  // 返回空的 JSON 对象
    )
  }
  
  @Sendable
  func fetchAlbumByID(req: Request) async throws -> AlbumResponse {
    let userID = try req.authenticatedUserID
    guard let albumID = req.parameters.get("albumID", as: UUID.self) else {
      throw Abort(.badRequest, reason: "无效的专辑 ID")
    }
    
    // 检查是否是系统专辑ID
    let systemAlbumID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    if albumID == systemAlbumID {
      throw Abort(.notFound, reason: "专辑不存在")
    }
    
    let cacheKey = CacheConfig.KeyBuilder.album(
      albumID: albumID,
      userID: userID
    )
    if let cacheResponse = try? await req.cache.get(
      forKey: cacheKey,
      as: AlbumResponse.self,
      from: req.redis
    ) { return cacheResponse }
    
    guard let album = try await Album.query(on: req.db)
      .filter(\.$id == albumID)
      .filter(\.$isDeleted == false)
      .with(\.$tags)
      .first() else {
      throw Abort(.notFound, reason: "专辑不存在")
    }
    let isFavorite = try await Favorite.query(on: req.db)
      .filter(\.$user.$id == userID)
      .filter(\.$album.$id == albumID)
      .first() != nil
    
    let response = AlbumResponse(
      id: try album.requireID(),
      title: album.title,
      description: album.description,
      cover: album.cover,
      audioCount: album.audioCount,
      playCount: album.playCount,
      favoriteCount: album.favoriteCount,
      wordCount: album.wordCount,
      category: album.category,
      isFavorite: isFavorite,
      tags: album.tags
        .map { TagResponse(id: try! $0.requireID(), name: $0.name)},
      createdAt: album.createdAt,
      updatedAt: album.updatedAt
    )
    
    do {
      try await req.cache
        .set(
          response,
          forKey: cacheKey,
          duration: CacheConfig.Duration.medium,
          type: .album,
          on: req.redis
        )
    } catch {
      LogManager.shared.error("缓存失败", context: "\(error)")
    }
    return response
  }
  
  @Sendable
  func fetch(req: Request) async throws -> AlbumWithRecentAudioResponse {
    let userID = try req.authenticatedUserID
    let query = try req.query.decode(FetchQuery.self)
    let cacheKey = CacheConfig.KeyBuilder.albumsAll(query: query, userID: userID)
    
      // 尝试从缓存获取
      //    if let cachedResponse = try? await req.cache.get(
      //      forKey: cacheKey,
      //      as: AlbumWithRecentAudioResponse.self,
      //      from: req.redis
      //    ) {
      //      return cachedResponse
      //    }
    
    let systemID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    
    async let recentAudios = try await Audio.query(on: req.db)
      .filter(\.$isDeleted == false)
      .join(Album.self, on: \Audio.$album.$id == \Album.$id)
      .filter(Album.self, \.$id != systemID) // 过滤掉系统专辑下的音频
      .with(\.$album)
      .sort(\.$createdAt, .descending)
      .limit(5)
      .all()
    
    async let albumPage = try await Album.query(on: req.db)
      .filter(\Album.$isDeleted == false)
      .filter(\Album.$id != systemID) // 过滤掉系统专辑
      .with(\Album.$tags)
      .sort(\Album.$updatedAt, .descending)
      .paginate(PageRequest(page: query.page, per: query.per))
    
      // 构建响应
    let response = AlbumWithRecentAudioResponse(
      albums: try await convertToResponsePage(
        pageResponse: await albumPage, userID: userID, req: req),
      recentAudios: try await recentAudios
    )
    
      // 缓存响应
    do {
      try await req.cache
        .set(
          response,
          forKey: cacheKey,
          duration: CacheConfig.Duration.medium,
          type: .album,
          on: req.redis
        )
    } catch {
      log.error("缓存失败", context: "\(error)")
    }
    return response
  }
  
  @Sendable
  func fetchByCategory(req: Request) async throws -> AlbumWithRecentAudioResponse {
    let userID = try req.authenticatedUserID
    guard
      let categoryString = req.parameters.get("category"),
      let category = Album.Category(rawValue: categoryString)
    else {
      throw Abort(.badRequest, reason: "无效的分类")
    }
    let query = try req.query.decode(FetchQuery.self)
    let cacheKey = CacheConfig.KeyBuilder.albumsByCategory(
      category: category.rawValue,
      query: query,
      userID: userID
    )
    if let cachedResponse = try? await req.cache.get(
      forKey: cacheKey,
      as: AlbumWithRecentAudioResponse.self,
      from: req.redis
    ) {
      return cachedResponse
    }
    
    let systemAlbumID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    
    async let recentAudios = try await Audio.query(on: req.db)
      .join(Album.self, on: \Audio.$album.$id == \Album.$id)
      .filter(Album.self, \.$category == category)
      .filter(Album.self, \.$id != systemAlbumID) // 过滤掉系统专辑
      .filter(\.$isDeleted == false)
      .with(\.$album)
      .sort(\.$createdAt, .descending)
      .limit(5)
      .all()
    
    async let pageResponse = Album.query(on: req.db)
      .filter(\.$isDeleted == false)
      .filter(\.$id != systemAlbumID) // 过滤掉系统专辑
      .filter(\.$category == category)
      .with(\.$tags)
      .sort(\.$updatedAt, .descending)
      .paginate(PageRequest(page: query.page, per: query.per))
    
    let response: AlbumController.AlbumWithRecentAudioResponse = AlbumWithRecentAudioResponse(
      albums: try await convertToResponsePage(
        pageResponse: await pageResponse, userID: userID, req: req),
      recentAudios: try await recentAudios
    )
    
    do {
      try await req.cache.set(
        response,
        forKey: cacheKey,
        duration: CacheConfig.Duration.medium,
        type: .album,
        on: req.redis
      )
    }
    
    return response
  }
  
  @Sendable
  func getByTag(req: Request) async throws -> AlbumWithRecentAudioResponse {
    let userID: UUID = try req.authenticatedUserID
    guard let tagIDString: String = req.parameters.get("tagID"),
          let tagID: UUID = UUID(uuidString: tagIDString)
    else {
      throw Abort(.badRequest, reason: "无效的标签ID")
    }
    let query: AlbumController.TagQuery = try req.query.decode(TagQuery.self)
    
      // 1. 添加参数验证
    guard query.page ?? 1 > 0 else {
      throw Abort(.badRequest, reason: "页码必须大于0")
    }
    
      // 2. 使用可选链和空合并运算符简化 tag 查询
    guard
      (try await Tag.query(on: req.db)
        .filter(\.$isDeleted == false)
        .filter(\.$id == tagID)
        .first()) != nil
    else {
      throw Abort(.notFound, reason: "标签不存在")
    }
    
    let page = query.page ?? 1
    let per = min(query.per ?? 20, 100)
    
      // 3. 优化缓存键的构建
    let cacheKey = CacheConfig.KeyBuilder.albumsByTag(tagID: tagID, query: query, userID: userID)
    
      // 4. 尝试从缓存获取
    if let cachedResponse = try? await req.cache.get(
      forKey: cacheKey, as: AlbumWithRecentAudioResponse.self, from: req.redis
    ) {
      return cachedResponse
    }
    
    let systemAlbumID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    
      // 5. 优化查询性能
    async let pageResponse = Album.query(on: req.db)
      .join(AlbumTag.self, on: \Album.$id == \AlbumTag.$album.$id)
      .filter(AlbumTag.self, \.$tag.$id == tagID)
      .filter(\.$isDeleted == false)
      .filter(\.$id != systemAlbumID) // 过滤掉系统专辑
      .with(\.$tags)
      .sort(\.$updatedAt, .descending)
      .paginate(PageRequest(page: page, per: per))
    
      // 6. 优化最近音频查询
      //    let oneWeekAgo = Date().addingTimeInterval(-7 * 24 * 60 * 60)
    async let recentAudios = Audio.query(on: req.db)
      .join(Album.self, on: \Audio.$album.$id == \Album.$id)
      .join(AlbumTag.self, on: \Album.$id == \AlbumTag.$album.$id)
      .filter(AlbumTag.self, \.$tag.$id == tagID)
      .filter(\.$isDeleted == false)
      .filter(Album.self, \.$isDeleted == false)
      .filter(Album.self, \.$id != systemAlbumID) // 过滤掉系统专辑
      .with(\.$album)
      //      .filter(\.$createdAt >= oneWeekAgo)
      .sort(\.$createdAt, .descending)
      .limit(5)
      .all()
    
    let response = try await AlbumWithRecentAudioResponse(
      albums: convertToResponsePage(pageResponse: await pageResponse, userID: userID, req: req),
      recentAudios: recentAudios
    )
    
      // 7. 优化缓存存储
    do {
      try await req.cache.set(
        response,
        forKey: cacheKey,
        duration: CacheConfig.Duration.medium,
        type: .album,
        on: req.redis
      )
    } catch {
      log.error("缓存失败", context: "\(error)")
    }
    return response
  }
  
  @Sendable
  func search(req: Request) async throws -> SearchResponse {
    let startTime = DispatchTime.now()
    
    let userID = try req.authenticatedUserID
    let query = try req.query.decode(SearchQuery.self)
    
    log.info("开始搜索请求", context: """
        - 接收到搜索词: \(query.search)
        - 搜索字段: \(String(describing: query.searchField))
        - 搜索范围: \(query.effectiveSearchScope)
        - 排序字段: \(query.sortBy)
        - 排序顺序: \(query.order)
        - 分类: \(String(describing: query.category))
        """)
    
      // 缓存键
    let cacheKey = CacheConfig.KeyBuilder.search(query: query, userID: userID)
    
      // 尝试从缓存获取
    if let cachedResponse = try? await req.cache.get(
      forKey: cacheKey,
      as: SearchResponse.self,
      from: req.redis
    ) {
      LogManager.shared.log(.info, "命中缓存", format: .standard)
      
      return cachedResponse
    }
    
      // 参数验证和清理
    let cleanedSearch = query.search.trimmingCharacters(in: .whitespacesAndNewlines)
    
      // 并发执行搜索
    async let albumsResult: Page<AlbumResponse> =
    (query.effectiveSearchScope == .albums || query.effectiveSearchScope == .all)
    ? searchAlbums(req: req, search: cleanedSearch, query: query)
    : Page(items: [], metadata: .init(page: 1, per: 1, total: 0))
    
    async let audiosResult: Page<AudioSearchResponse> =
    (query.effectiveSearchScope == .audios || query.effectiveSearchScope == .all)
    ? searchAudios(req: req, search: cleanedSearch, query: query)
    : Page(items: [], metadata: .init(page: 1, per: 1, total: 0))
    
    let response = try await SearchResponse(
      albums: albumsResult,
      audios: audiosResult
    )
    
      // 缓存结果
    do {
      try await req.cache.set(
        response,
        forKey: cacheKey,
        duration: CacheConfig.Duration.short,
        type: .search,
        on: req.redis
      )
      LogManager.shared.info("结果已缓存", format: .standard)
    } catch {
      log.error("缓存失败", context: "\(error)")
    }
    
    let timeInterval = Double(DispatchTime.now().uptimeNanoseconds - startTime.uptimeNanoseconds) / 1_000_000_000
    log.debug("搜索流程执行完毕", context: "耗时: \(timeInterval)秒")
    
    return response
  }
  
  private func searchAlbums(req: Request, search cleanedSearch: String, query: SearchQuery)
  async throws -> Page<AlbumResponse> {
    
    var albumQuery = Album.query(on: req.db)
      .filter(\.$isDeleted == false)
    
    // 过滤掉系统专辑
    let systemAlbumID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    albumQuery = albumQuery.filter(\.$id != systemAlbumID)
    
    if !cleanedSearch.isEmpty {
      let searchTerm = SearchUtils.prepareSearchTerm(cleanedSearch)
      let isShortChinese = SearchUtils.isShortChineseQuery(cleanedSearch)
      
      log.debug("进入到专辑进行搜索", context: """
      - 初步清理后的搜索词: \(cleanedSearch)
      - 处理后的搜索词: \(searchTerm)
      - 是否是短中文: \(isShortChinese)
      - 搜索字段限定为: \(String(describing: query.searchField))
    """)
      
      switch query.searchField {
        case .title:
          if isShortChinese {
            albumQuery = albumQuery
              .unique()
              .filter(\.$title ~~ cleanedSearch)
          } else {
            let rawSQL = "MATCH(albums.title) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
            albumQuery = albumQuery
              .unique()
              .group(.or) { or in
                or.filter(.sql(unsafeRaw: rawSQL))
                or.filter(\.$title ~~ cleanedSearch)
              }
          }
        case .description:
          if isShortChinese {
            albumQuery = albumQuery
              .unique()
              .filter(\.$description ~~ cleanedSearch)
          } else {
            let rawSQL = "MATCH(albums.description) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
            albumQuery = albumQuery
              .unique()
              .group(.or) { or in
                or.filter(.sql(unsafeRaw: rawSQL))
                or.filter(\.$description ~~ cleanedSearch)
              }
          }
        case .all, .none:
          albumQuery = albumQuery
            .unique()
            .group(.or) { or in
              if isShortChinese {
                or.filter(\.$title ~~ cleanedSearch)
                or.filter(\.$description ~~ cleanedSearch)
              } else {
                let titleSQL = "MATCH(albums.title) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
                let descSQL = "MATCH(albums.description) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
                or.filter(.sql(unsafeRaw: titleSQL))
                or.filter(.sql(unsafeRaw: descSQL))
                or.filter(\.$title ~~ cleanedSearch)
                or.filter(\.$description ~~ cleanedSearch)
              }
            }
        default:
          break
      }
    }
    
      // 分类过滤
    if let category = query.category {
      albumQuery = albumQuery.filter(\.$category == category)
      log.debug("限定分类", context: "\(category)")
    }
    
      // 标签过滤
    if let tagName = query.tagName {
      albumQuery = albumQuery
        .join(AlbumTag.self, on: \Album.$id == \AlbumTag.$album.$id)
        .join(Tag.self, on: \AlbumTag.$tag.$id == \Tag.$id)
        .filter(Tag.self, \.$name == tagName)
      log.debug("限定标签", context: "\(tagName)")
    }
    
      // 排序逻辑
    switch query.sortBy {
      case .title:
        albumQuery = albumQuery.sort(\.$title, query.order == .ascending ? .ascending : .descending)
      case .updatedAt:
        albumQuery = albumQuery.sort(\.$updatedAt, query.order == .ascending ? .ascending : .descending)
      case .playCount:
        albumQuery = albumQuery.sort(\.$playCount, query.order == .ascending ? .ascending : .descending)
      case .favoriteCount:
        albumQuery = albumQuery.sort(\.$favoriteCount, query.order == .ascending ? .ascending : .descending)
      default:
        albumQuery = albumQuery.sort(\.$updatedAt, .descending)
    }
    
    log.debug("排序规则", context: """
      - \(query.sortBy)
      - \(query.order)
    """)
    
      // 获取分页数据
    let pagedAlbums = try await albumQuery
      .with(\.$tags)
      .paginate(PageRequest(page: query.page, per: query.per))
    
    log.info("搜到的专辑数量", context: "\(pagedAlbums.items.count)")
    
      // 获取收藏状态
    var favoriteStatus: [UUID: Bool] = [:]
    if let userID = try? req.authenticatedUserID {
      let favorites = try await Favorite.query(on: req.db)
        .unique()
        .filter(\.$user.$id == userID)
        .filter(\.$album.$id ~~ pagedAlbums.items.compactMap { $0.id })
        .all()
      
      favoriteStatus = Dictionary(
        favorites.map { ($0.$album.id, true) },
        uniquingKeysWith: { first, _ in first }
      )
    }
    
      // 转换为响应
    return Page(
      items: pagedAlbums.items.map { album in
        AlbumResponse(
          id: try! album.requireID(),
          title: album.title,
          description: album.description,
          cover: album.cover,
          audioCount: album.audioCount,
          playCount: album.playCount,
          favoriteCount: album.favoriteCount,
          wordCount: album.wordCount,
          category: album.category,
          isFavorite: favoriteStatus[album.id ?? UUID()] ?? false,
          tags: album.tags.map { TagResponse(id: try! $0.requireID(), name: $0.name) },
          createdAt: album.createdAt,
          updatedAt: album.updatedAt
        )
      },
      metadata: pagedAlbums.metadata
    )
  }
  
  private func searchAudios(req: Request, search cleanedSearch: String, query: SearchQuery)
  async throws -> Page<AudioSearchResponse> {
    
    // 系统ID
    let systemID = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
    
    var audioQuery = Audio.query(on: req.db)
      .filter(\.$isDeleted == false)
      .filter(\.$id != systemID) // 过滤掉系统音频
      .join(Album.self, on: \Audio.$album.$id == \Album.$id)
      .filter(Album.self, \.$id != systemID) // 过滤掉系统专辑下的音频
      .unique()
    
    if !cleanedSearch.isEmpty {
      let searchTerm = SearchUtils.prepareSearchTerm(cleanedSearch)
      let isShortChinese = SearchUtils.isShortChineseQuery(cleanedSearch)
      
      log.debug("进入到音频进行搜索", context: """
      - 初步清理后的搜索词: \(cleanedSearch)
      - 处理后的搜索词: \(searchTerm)
      - 是否是短中文: \(isShortChinese)
      - 搜索字段限定为: \(String(describing: query.searchField))
    """)
      
      switch query.searchField {
        case .title:
          
          if isShortChinese {
            audioQuery = audioQuery.filter(\.$title ~~ cleanedSearch)
          } else {
            let rawSQL = "MATCH(audios.title) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
            audioQuery = audioQuery.group(.or) { or in
              or.filter(.sql(unsafeRaw: rawSQL))
              or.filter(\.$title ~~ cleanedSearch)
            }
          }
        case .description:
          if isShortChinese {
            audioQuery = audioQuery.filter(\.$description ~~ cleanedSearch)
          } else {
            let rawSQL = "MATCH(audios.description) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
            audioQuery = audioQuery.filter(.sql(unsafeRaw: rawSQL))
          }
        case .all, .none:
          audioQuery = audioQuery.group(.or) { or in
            if isShortChinese {
              or.filter(\.$title ~~ cleanedSearch)
              or.filter(\.$author ~~ cleanedSearch)
              or.filter(\.$description ~~ cleanedSearch)
            } else {
              let titleSQL = "MATCH(audios.title) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
              let descSQL = "MATCH(audios.description) AGAINST('\(searchTerm)' IN BOOLEAN MODE)"
              or.filter(.sql(unsafeRaw: titleSQL))
              or.filter(.sql(unsafeRaw: descSQL))
              or.filter(\.$title ~~ cleanedSearch)
              or.filter(\.$description ~~ cleanedSearch)
            }
          }
        default:
          break
      }
    }
    
      // 获取分页数据
    let results = try await audioQuery
      .with(\.$album)
      .paginate(PageRequest(page: query.page, per: query.per))
    
    log.info("收到到的音频数量", context: "\(results.items.count)")
    
    return results.map { audio in
      AudioSearchResponse(
        id: try! audio.requireID(),
        title: audio.title,
        description: audio.description,
        duration: audio.duration,
        cover: audio.cover,
        author: audio.author,
        url: audio.url,
        size: audio.size,
        albumID: try! audio.album.requireID(),
        albumTitle: audio.album.title,
        albumCover: audio.album.cover,
        createdAt: audio.createdAt,
        updatedAt: audio.updatedAt
      )
    }
  }
}
